Completed
Push — master ( d11c3b...71f351 )
by Pieter
02:36
created

main.js ➔ ... ➔ update_window   A

Complexity

Conditions 1
Paths 9

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 5
rs 9.4285
c 1
b 0
f 0
cc 1
nc 9
nop 0
1
var eventQueue = [];
2
var svg;
3
var element;
4
var drawingArea;
5
var width;
6
var height;
7
var volume = 0.6;
8
var orgRepoFilterNames = [];
9
var header = $('header');
10
11
var scale_factor = 6,
12
    note_overlap = 2,
13
    note_timeout = 300,
14
    current_notes = 0,
15
    max_life = 20000;
16
17
var svg_background_color_online  = 'black',
18
    svg_background_color_offline = 'black',
19
    svg_text_color               = '#FFFFFF',
20
    edit_color                   = '#FFFFFF',
21
    total_sounds = 51;
22
23
var celesta = [],
24
    clav = [],
25
    swells = [],
26
    all_loaded = false;
27
28
var socket = new WebSocket("ws://localhost:1337/ws");
29
30
socket.addEventListener("message", function (data) {
31
    var json = JSON.parse(data.data);
32
33
    if (json.hasOwnProperty('connectedUsers')) {
34
        $('.online-users-count').html(json.connectedUsers);
35
36
        return;
37
    }
38
39
    json.forEach(function (event) {
40
        if (!isEventInQueue(event)) {
41
            // Filter out events only specified by the user
42
            if (orgRepoFilterNames != []) {
43
                // Don't consider pushes to github.io repos when org filter is on
44
                if (new RegExp(orgRepoFilterNames.join("|")).test(event.repoName) && event.repoName.indexOf('github.io') == -1) {
45
                    eventQueue.push(event);
46
                }
47
            } else {
48
                eventQueue.push(event);
49
            }
50
        }
51
    });
52
53
    // Don't let the eventQueue grow more than 1000
54
    if (eventQueue.length > 1000) eventQueue = eventQueue.slice(0, 1000);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
55
});
56
57
socket.onopen = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
58
    $('svg').css('background-color', svg_background_color_online);
59
    header.css('background-color', svg_background_color_online);
60
    $('.offline-text').css('visibility', 'hidden');
61
    $('.events-remaining-text').css('visibility', 'visible');
62
    $('.events-remaining-value').css('visibility', 'visible');
63
    $('.online-users-div').css('visibility', 'visible');
64
};
65
66
socket.onclose = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
67
    $('svg').css('background-color', svg_background_color_offline);
68
    header.css('background-color', svg_background_color_offline);
69
    $('.offline-text').css('visibility', 'visible');
70
    $('.events-remaining-text').css('visibility', 'visible');
71
    $('.events-remaining-value').css('visibility', 'visible');
72
};
73
74
socket.onerror = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
75
    $('svg').css('background-color', svg_background_color_offline);
76
    header.css('background-color', svg_background_color_offline);
77
    $('.offline-text').css('visibility', 'visible');
78
    $('.events-remaining-text').css('visibility', 'visible');
79
    $('.events-remaining-value').css('visibility', 'visible');
80
};
81
82
/**
83
* This function checks whether an event is already in the queue
84
*/
85
function isEventInQueue(event){
86
  for(var i=0; i<eventQueue.length; i++){
87
    if(eventQueue[i].id == event.id)
88
      return true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
89
  }
90
  return false;
91
}
92
93
$(function(){
94
  element = document.documentElement;
95
  drawingArea = document.getElementsByTagName('#area')[0];
96
  width  = window.innerWidth || element.clientWidth || drawingArea.clientWidth;
97
  height = (window.innerHeight - header.height()) || (element.clientHeight - header.height()) || (drawingArea.clientHeight - header.height());
98
  $('svg').css('background-color', svg_background_color_online);
99
  header.css('background-color', svg_background_color_online);
100
  $('svg text').css('color', svg_text_color);
101
  $('#volumeSlider').slider({
102
    'max': 100,
103
    'min': 0,
104
    'value': volume*100,
105
    'slide' : function(event, ui){
106
      volume = ui.value/100.0;
107
      Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
108
    },
109
    'change' : function(event, ui){
110
      volume = ui.value/100.0;
111
      Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
112
    }
113
  });
114
115
  // Main drawing area
116
  svg = d3.select("#area").append("svg");
1 ignored issue
show
Bug introduced by
The variable d3 seems to be never declared. If this is a global, consider adding a /** global: d3 */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
117
  svg.attr({width: width, height: height});
118
  svg.style('background-color', svg_background_color_online);
119
120
  // For window resizes
121
  var update_window = function() {
122
      width  = window.innerWidth || element.clientWidth || drawingArea.clientWidth;
123
      height = (window.innerHeight - header.height()) || (element.clientHeight - header.height()) || (drawingArea.clientHeight - header.height());
124
      svg.attr("width", width).attr("height", height);
125
  };
126
  window.onresize = update_window;
127
  update_window();
128
129
  var loaded_sounds = 0;
130
  var sound_load = function(r) {
0 ignored issues
show
Unused Code introduced by
The parameter r is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
131
      loaded_sounds += 1;
132
      if (loaded_sounds == total_sounds) {
133
          all_loaded = true;
134
          setTimeout(playFromQueueExchange1, Math.floor(Math.random() * 1000));
135
      }
136
  };
137
138
  // Load sounds
139
  for (var i = 1; i <= 24; i++) {
140
      if (i > 9) {
141
          fn = 'c0' + i;
0 ignored issues
show
Bug introduced by
The variable fn seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.fn.
Loading history...
142
      } else {
143
          fn = 'c00' + i;
144
      }
145
      celesta.push(new Howl({
0 ignored issues
show
Bug introduced by
The variable Howl seems to be never declared. If this is a global, consider adding a /** global: Howl */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
146
          src : [
147
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/celesta/' + fn + '.ogg',
148
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/celesta/' + fn + '.mp3'
149
          ],
150
          volume : 0.7,
151
          onload : sound_load(),
152
          buffer: true
153
      }));
154
      clav.push(new Howl({
155
          src : [
156
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/clav/' + fn + '.ogg',
157
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/clav/' + fn + '.mp3'
158
          ],
159
          volume : 0.4,
160
          onload : sound_load(),
161
          buffer: true
162
      }))
163
  }
164
165
  for (var i = 1; i <= 3; i++) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 139. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
166
      swells.push(new Howl({
167
          src : [
168
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/swells/swell' + i + '.ogg', 
169
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/swells/swell' + i + '.mp3'
170
          ],
171
          volume : 1,
172
          onload : sound_load(),
173
          buffer: true
174
      }));
175
  }
176
177
  Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
178
179
  // Make header and footer visible
180
  $('body').css('visibility', 'visible');
181
182
  $('#org-repo-filter-name').on('input', function() {
183
    orgRepoFilterNames = $('#org-repo-filter-name').val().split(' ');
184
    eventQueue = [];
185
  });
186
187
});
188
189
/**
190
* Randomly selects a swell sound and plays it
191
*/
192
function playRandomSwell() {
193
    var index = Math.round(Math.random() * (swells.length - 1));
194
    swells[index].play();
195
}
196
197
/**
198
* Plays a sound(celesta and clav) based on passed parameters
199
*/
200
function playSound(size, type) {
201
    var max_pitch = 100.0;
202
    var log_used = 1.0715307808111486871978099;
203
    var pitch = 100 - Math.min(max_pitch, Math.log(size + log_used) / Math.log(log_used));
204
    var index = Math.floor(pitch / 100.0 * Object.keys(celesta).length);
205
    
206
    index += Math.floor(Math.random() * 4) - 2;
207
    index = Math.min(Object.keys(celesta).length - 1, index);
208
    index = Math.max(1, index);
209
    if (current_notes < note_overlap) {
210
        current_notes++;
211
        if (type == 'IssuesEvent' || type == 'IssueCommentEvent') {
212
            clav[index].play();
213
        } else if(type == 'PushEvent') {
214
            celesta[index].play();
215
        }else{
216
          playRandomSwell();
217
        }
218
        setTimeout(function() {
219
            current_notes--;
220
        }, note_timeout);
221
    }
222
}
223
224
// Following are the n numbers of event consumers
225
// consuming n events each per second with a random delay between them
226
227
function playFromQueueExchange1(){
228
  var event = eventQueue.shift();
229
  if(event != null && event.message != null && svg != null){
230
    playSound(event.message.length*1.1, event.type);
231
    if(!document.hidden)
232
      drawEvent(event, svg);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
233
  }
234
  setTimeout(playFromQueueExchange1, Math.floor(Math.random() * 1000) + 500);
235
  $('.events-remaining-value').html(eventQueue.length);
236
}
237
238
// This method capitalizes the string in place
239
String.prototype.capitalize = function(all){
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type String. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
240
    if(all){
241
      return this.split(' ').map(function(e){
242
        return e.capitalize().join(' ');
243
      });
244
    }else{
245
         return this.charAt(0).toUpperCase() + this.slice(1);
246
    }
247
};
248
249
function drawEvent(data, svg_area) {
250
    var starting_opacity = 1;
251
    var opacity = 1 / (100 / data.message.length);
252
    if (opacity > 0.5) opacity = 0.5;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Unused Code introduced by
The assignment to variable opacity seems to be never used. Consider removing it.
Loading history...
253
254
    var size = data.message.length;
255
    var label_text;
256
    var ring_radius = 80;
257
    var ring_anim_duration = 3000;
258
    svg_text_color = '#FFFFFF';
259
260
    switch(data.type){
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
261
      case "PushEvent":
262
        label_text = data.actorName.capitalize() + " pushed to " + data.repoName;
263
        edit_color = '#22B65D';
264
      break;
265
      case "PullRequestEvent":
266
        label_text = data.actorName.capitalize() + " " +
267
          data.action + " " + " a PR for " + data.repoName;
268
          edit_color = '#8F19BB';
269
          ring_anim_duration = 10000;
270
          ring_radius = 600;
271
      break;
272
      case "IssuesEvent":
273
        label_text = data.actorName.capitalize() + " " +
274
          data.action + " an issue in " + data.repoName;
275
          edit_color = '#ADD913';
276
      break;
277
      case "IssueCommentEvent":
278
        label_text = data.actorName.capitalize() + " commented in " + data.repoName;
279
        edit_color = '#FF4901';
280
      break;
281
      case "ForkEvent":
282
        label_text = data.actorName.capitalize() + " forked " + data.repoName;
283
        edit_color = '#0184FF';
284
        break;
285
      case "CreateEvent":
286
        label_text = data.actorName.capitalize() + " created " + data.repoName;
287
        edit_color = '#00C0C0';
288
      break;
289
      case "WatchEvent":
290
        label_text = data.actorName.capitalize() + " watched " + data.repoName;
291
        edit_color = '#E60062';
292
      break;
293
    }
294
295
    var no_label = false;
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
296
    var type = data.type;
297
298
    var abs_size = Math.abs(size);
299
    size = Math.max(Math.sqrt(abs_size) * scale_factor, 3);
300
301
    Math.seedrandom(data.message);
302
    var x = Math.random() * (width - size) + size;
303
    var y = Math.random() * (height - size) + size;
304
305
    var circle_group = svg_area.append('g')
306
        .attr('transform', 'translate(' + x + ', ' + y + ')')
307
        .attr('fill', edit_color)
308
        .style('opacity', starting_opacity);
309
310
    var ring = circle_group.append('circle');
311
    ring.attr({r: size, stroke: 'none'});
312
    ring.transition()
313
        .attr('r', size + ring_radius)
314
        .style('opacity', 0)
315
        .ease(Math.sqrt)
316
        .duration(ring_anim_duration)
317
        .remove();
318
319
    var circle_container = circle_group.append('a');
320
    circle_container.attr('xlink:href', data.eventURL);
321
    circle_container.attr('target', '_blank');
322
    circle_container.attr('fill', svg_text_color);
323
324
    var circle = circle_container.append('circle');
325
    circle.classed(type, true);
326
    circle.attr('r', size)
327
      .attr('fill', edit_color)
328
      .transition()
329
      .duration(max_life)
330
      .style('opacity', 0)
331
      .remove();
332
333
    circle_container.on('mouseover', function() {
334
      circle_container.append('text')
335
          .text(label_text)
0 ignored issues
show
Bug introduced by
The variable label_text seems to not be initialized for all possible execution paths. Are you sure text handles undefined variables?
Loading history...
336
          .classed('label', true)
337
          .attr('text-anchor', 'middle')
338
          .attr('font-size', '0.8em')
339
          .transition()
340
          .delay(1000)
341
          .style('opacity', 0)
342
          .duration(2000)
343
          .each(function() { no_label = true; })
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
344
          .remove();
345
    });
346
347
    var text = circle_container.append('text')
348
        .text(label_text)
0 ignored issues
show
Bug introduced by
The variable label_text seems to not be initialized for all possible execution paths. Are you sure text handles undefined variables?
Loading history...
349
        .classed('article-label', true)
350
        .attr('text-anchor', 'middle')
351
        .attr('font-size', '0.8em')
352
        .transition()
353
        .delay(2000)
354
        .style('opacity', 0)
355
        .duration(5000)
356
        .each(function() { no_label = true; })
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
357
        .remove();
358
359
  // Remove HTML of decayed events
360
  // Keep it less than 50
361
  if($('#area svg g').length > 50){
362
    $('#area svg g:lt(10)').remove();
363
  }
364
}
365